﻿using System;
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;

// Copy http://www.blueedge.nl/weblog/post/WCF-ExceptionHandling-in-Silverlight.aspx

namespace MailRuWrapper.Server.Silverlight
{
    public abstract class WcfBehaviorAttributeBase : Attribute, IServiceBehavior
    {
        private readonly Type _behaviorType;

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="typeBehavior">IDispatchMessageInspector, IErrorHandler of IParameterInspector</param>
        protected WcfBehaviorAttributeBase(Type typeBehavior)
        {
            _behaviorType = typeBehavior;
        }

        void IServiceBehavior.AddBindingParameters(ServiceDescription serviceDescription, System.ServiceModel.ServiceHostBase serviceHostBase, System.Collections.ObjectModel.Collection<ServiceEndpoint> endpoints, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
        {
        }

        void IServiceBehavior.ApplyDispatchBehavior(ServiceDescription serviceDescription, System.ServiceModel.ServiceHostBase serviceHostBase)
        {
            object _behavior;
            try
            {
                _behavior = Activator.CreateInstance(_behaviorType);
            }
            catch (MissingMethodException e)
            {
                throw new ArgumentException("The Type specified in the BehaviorAttribute constructor must have a public empty constructor.", e);
            }
            catch (InvalidCastException e)
            {
                throw new ArgumentException("The Type specified in the BehaviorAttribute constructor must implement IDispatchMessageInspector, IParamaterInspector of IErrorHandler", e);
            }

            foreach (ChannelDispatcher _channelDispatcher in serviceHostBase.ChannelDispatchers)
            {
                if (_behavior is IParameterInspector)
                {
                    foreach (EndpointDispatcher _epDisp in _channelDispatcher.Endpoints)
                    {
                        foreach (DispatchOperation _op in _epDisp.DispatchRuntime.Operations)
                            _op.ParameterInspectors.Add((IParameterInspector)_behavior);
                    }
                }
                else if (_behavior is IErrorHandler)
                {
                    _channelDispatcher.ErrorHandlers.Add((IErrorHandler)_behavior);
                }
                else if (_behavior is IDispatchMessageInspector)
                {
                    foreach (EndpointDispatcher _endpointDispatcher in _channelDispatcher.Endpoints)
                    {
                        _endpointDispatcher.DispatchRuntime.MessageInspectors.Add((IDispatchMessageInspector)_behavior);
                    }
                }
            }

        }

        void IServiceBehavior.Validate(ServiceDescription serviceDescription, System.ServiceModel.ServiceHostBase serviceHostBase)
        {
        }
    }

}


